/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.control;

import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;
import org.zhiqim.kernel.model.seqs.Sequence;
import org.zhiqim.kernel.util.DateTimes;

/**
 * 线程操作者
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class Threader extends Threadx implements Runnable
{
    private static final Log log = LogFactory.getLog(Threader.class);
    private static final Sequence sequence = new Sequence();
    
    private final ThreaderController controller;
    private final String threadName;
    
    //线程活动状态
    private volatile boolean idle = true;
    private volatile long idleTimeMs = System.currentTimeMillis();
    
    public Threader(ThreaderController controller)
    {
        this.controller = controller;
        this.threadName = controller.getThreadGroup().getName() + "-" + sequence.next();
    }
    
    /**************************************************************************************/
    //线程组&线程名&线程回调循环操作
    /**************************************************************************************/
    
    @Override
    public String getThreadName()
    {
        return threadName;
    }
    
    @Override
    protected ThreadGroup getThreadGroup()
    {
        return controller.getThreadGroup();
    }
    
    @Override
    protected void loop()
    {
        Runnable command = controller.accept();
        if (command == null)
            return;
        
        try
        {
            idle = false;
            controller.active();
            command.run();
        }
        catch (Exception e)
        {
            log.error("线程池处理时异常：[%s]", e,  e.getMessage());
        }
        finally
        {
            idle = true;
            idleTimeMs = System.currentTimeMillis();
            controller.idle();
            command = null;
        }
    }
    
    /**************************************************************************************/
    //获取运行时属性
    /**************************************************************************************/
    
    public boolean isActive()
    {
        return !idle;
    }
    
    public boolean isIdle()
    {
        return idle;
    }
    
    public long getIdleTimeMs()
    {
        return idleTimeMs;
    }
    
    public String getIdleTimeString()
    {
        return DateTimes.toDateTimeString(idleTimeMs);
    }
    
    public boolean isIdleTimeout(long maxIdleTimeMs)
    {
        return idle && (System.currentTimeMillis() - idleTimeMs - maxIdleTimeMs) > 0;
    }
}
